package me.zhangsanfeng.gpss.common.utils;

import me.zhangsanfeng.gpss.common.entity.BaseEntity;
import me.zhangsanfeng.gpss.common.entity.Sorter;
import org.springframework.data.domain.*;
import org.springframework.data.jpa.repository.JpaRepository;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class QueryConditionUtil {

    /**
     *
     * @param t 实例
     * @param isPage 是否分页
     * @param <T> 实体类型
     * @return
     */
    public static <T> Map<String,Object> getWhereCondition(T t,boolean isPage,boolean isSort){
        Class<BaseEntity> baseEntityClass = BaseEntity.class;
        Class<?> aClass = t.getClass();
        //传入参数是BaseEntity的子类
        boolean assignableFrom = baseEntityClass.isAssignableFrom(aClass);
        Sorter sorter = null;
        String asc = null;
        String desc = null;
        Integer pageNum = null;
        Integer pageSize = null;
        Map<String,Object> map = new HashMap<>();
        if (assignableFrom){
            map.put("example",Example.of(t, ExampleMatcher.matchingAll()));
            try {
                //如果需要分页，反射取出分页参数
                if (isPage){
                    Method getPageNum = aClass.getMethod("getPageNum",new Class[]{});
                    Method getPageSize = aClass.getMethod("getPageSize", new Class[]{});
                    Object page = getPageNum.invoke(t, new Object[]{});
                    Object size = getPageSize.invoke(t, new Object[]{});
                    pageNum = (Integer) page;
                    pageSize = (Integer) size;
                }
                if (isSort){
                    Method getSorter = aClass.getMethod("getSorter", new Class[]{});
                    Object object = getSorter.invoke(t, new Object[]{});
                    sorter = (Sorter) object;
                    asc = sorter.getAsc();
                    desc = sorter.getDesc();
                }
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }



            /*排序条件*/
            if (isSort && (DataUtil.isNotEmpty(asc) || DataUtil.isNotEmpty(desc))){
                //优先级：desc,asc
                String prior = sorter.getPrior();

                /*取出传入排序字段，并封装成Sort实例*/
                Sort sortDesc = null;
                Sort sortAsc = null;
                if (DataUtil.isNotEmpty(desc)){
                    String[] descSplit = desc.split(",");
                    if (descSplit.length !=0){
                        sortDesc = new Sort(Sort.Direction.DESC,descSplit);
                    }else {
                        sortDesc = new Sort(Sort.Direction.DESC,desc);
                    }
                }
                if (DataUtil.isNotEmpty(asc)){
                    String[] ascSplit = asc.split(",");
                    if (ascSplit.length !=0){
                        sortAsc = new Sort(Sort.Direction.ASC,ascSplit);
                    }else {
                        sortAsc = new Sort(Sort.Direction.ASC,asc);
                    }
                }

                Sort sort = null;
                /*处理不同情况的分页操作*/
                if (DataUtil.isNotEmpty(desc) && DataUtil.isNotEmpty(asc)){
                    //降序、升序同时存在且有优先级的情况
                    if (DataUtil.isNotEmpty(prior)){
                        //先降序，后升序
                        if ("desc".equals(prior)){
                            sort = sortDesc.and(sortAsc);
                        }
                        if ("asc".equals(prior)){
                            sort = sortAsc.and(sortDesc);
                        }
                    }else {
                        //降序、升序同时存在但没有优先级的情况，先倒序再正序
                        sort = sortDesc.and(sortAsc);
                    }
                }else if (DataUtil.isNotEmpty(desc) && DataUtil.isEmpty(asc)){
                    //只有倒序的情况
                    sort = sortDesc;
                }else if (DataUtil.isNotEmpty(asc) && DataUtil.isEmpty(desc)){
                    //只有正序的情况
                    sort = sortAsc;
                }
                map.put("sort",sort);
            }

            /*分页条件*/
            if (isPage){
                Pageable pageable;
                if (isSort){
                    Sort sort = (Sort) map.get("sort");
                    pageable = PageRequest.of((pageNum - 1), pageSize, sort);
                }else {
                    pageable = PageRequest.of((pageNum - 1), pageSize);

                }
                map.put("page",pageable);
            }
        }
        return map;
    }

    public static List getQueryInstanceOfList(Map map, JpaRepository repository){
        Sort sort = (Sort) map.get("sort");
        Example example = (Example) map.get("example");
        //排序
        if (DataUtil.isNotEmpty(sort)){
            return repository.findAll(example,sort);
        }
        //不排序
        return repository.findAll(example);
    }

    public static Page getQueryInstanceOfPage(Map map, JpaRepository repository){
        Example example = (Example) map.get("example");
        Pageable page = (Pageable) map.get("page");
        return repository.findAll(example,page);
    }
}
